#include "reminderdialog.h"
#include "ui_reminderdialog.h"

#include <QDir>
#include <QCalendarWidget>
#include <QMessageBox>
#include <QUrl>
#include <QFileDialog>

ReminderDialog::ReminderDialog(QWidget *parent) :
    QDialog(parent, Qt::MSWindowsFixedSizeDialogHint),
    ui(new Ui::ReminderDialog)
{
    ui->setupUi(this);

    ui->from_dateTimeEdit->calendarWidget()->setFirstDayOfWeek(Qt::Monday);

    #ifndef Q_OS_WIN
        ui->system_checkBox->hide();
        ui->system_comboBox->hide();
        ui->system_spinBox->hide();
    #endif

    this->addSounds();

    ui->from_dateTimeEdit->setDisplayFormat(
                    (qApp->property("use_secconds").toBool()) ?
                    "dd.MM.yyyy HH:mm:ss" : "dd.MM.yyyy HH:mm"
                     );

    connect(ui->repeat_checkBox, SIGNAL(toggled(bool)), this, SLOT(toggleRepeatOptions(bool)));
    connect(ui->interval_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleIntervalOptions(int)));
    connect(ui->audio_toolButton, SIGNAL(clicked()), this, SLOT(startPlaySound()));
    connect(ui->dialog_checkBox, SIGNAL(toggled(bool)), this, SLOT(toggleDialogOptons(bool)));
    connect(ui->from_dateTimeEdit, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setIntervalText(QDateTime)));
    connect(ui->system_checkBox, SIGNAL(toggled(bool)), this, SLOT(toggleShutdownOptions(bool)));
    connect(ui->system_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(enableShutdownTimeout(int)));
    connect(ui->execute_toolButton, SIGNAL(clicked()), this, SLOT(chooseExecute()));
}

ReminderDialog::~ReminderDialog()
{
    if(ui) delete ui;
}

void ReminderDialog::accept()
{
    if(this->isCorrectReminder()) {
        QDialog::accept();
    }
}

void ReminderDialog::setDefaults()
{
    this->toggleRepeatOptions(false);
    this->toggleIntervalOptions(0);
    this->setReminderName(tr("New reminder"));
    this->setDialogText(tr("New reminder"));
    //this->setFromDate(QDateTime::currentDateTime().addSecs(60*60));
    {
        QDateTime dt = QDateTime::currentDateTime();
        dt.setTime(QTime(0,0));
        this->setFromDate(dt);
    }
    this->setAutodelete(false);
    this->setShutdown(false);
    this->setExecute(false);

    ui->repeat_checkBox->setChecked(false);
    ui->audio_checkBox->setChecked(true);
    ui->tooltip_checkBox->setChecked(false);
    ui->dialog_checkBox->setChecked(true);
    ui->audio_comboBox->setCurrentIndex(0);
    ui->execute_lineEdit->setText("");
    ui->execute_args_lineEdit->setText("");
    ui->system_comboBox->setEnabled(false);
    ui->missed_checkBox->setChecked(false);
}

void ReminderDialog::addSounds()
{
    QDir sounds(":/Sounds/sounds/");
    QStringList filter;
    filter << "*.wav" << "*.mp3";
    ui->audio_comboBox->addItems(sounds.entryList(filter));
}

void ReminderDialog::startPlaySound()
{
    emit this->playSound(ui->audio_comboBox->currentText());
}

void ReminderDialog::stopPlaySound()
{
    emit this->stopSound();
}

void ReminderDialog::toggleRepeatOptions(bool toggle)
{
    ui->repeat_groupBox->setShown(toggle);
    ui->autodelete_checkBox->setDisabled(toggle);
    if(ui->autodelete_checkBox->isChecked() && toggle){
        ui->autodelete_checkBox->setChecked(false);
    }
}

void ReminderDialog::setInterval(const QString &interval){
    int idx = 0;
    if(interval == tr("Minutely"))
        idx=0;
    else if(interval == tr("Hourly"))
        idx=1;
    else if(interval == tr("Daily"))
        idx=2;
    else if(interval == tr("Monthly"))
        idx=3;
    else if(interval == tr("Monthly (by day)"))
        idx=4;
    else if(interval == tr("Yearly"))
        idx=5;
    else if(interval == tr("Yearly (by day)"))
        idx=6;
    else if(interval == tr("Timeout"))
        idx=7;
    ui->interval_comboBox->setCurrentIndex(idx);
    this->setRepeat(true);
}

QString ReminderDialog::getInterval() const
{
    return ui->interval_comboBox->currentText();
}

int ReminderDialog::getIntervalIdx() const
{
    return ui->interval_comboBox->currentIndex();
}

void ReminderDialog::setRepeat(bool repeat)
{
    ui->repeat_checkBox->setChecked(repeat);
}

bool ReminderDialog::getRepeat() const
{
    return ui->repeat_checkBox->isChecked();
}

void ReminderDialog::setAutoclose(bool autoclose)
{
    ui->autoclose_checkBox->setChecked(autoclose);
}

bool ReminderDialog::getAutoclose() const
{
    return ui->autoclose_checkBox->isChecked();
}

void ReminderDialog::setMinutes(int minutes)
{
    if(minutes >= ui->minutes_spinBox->minimum() && minutes <= ui->minutes_spinBox->maximum())
        ui->minutes_spinBox->setValue(minutes);
}

int ReminderDialog::getMinutes() const
{
    return ui->minutes_spinBox->value();
}

void ReminderDialog::setHours(int hours)
{
    if(hours >= ui->hours_spinBox->minimum() && hours <= ui->hours_spinBox->maximum())
        ui->hours_spinBox->setValue(hours);
}

int ReminderDialog::getHours() const
{
    return ui->hours_spinBox->value();
}

int ReminderDialog::getTimeout() const
{
    int secs = ui->timeout_hours_spinBox->value()*60*60;
    secs += ui->timeout_minutes_spinBox->value()*60;
    return secs;
}

void ReminderDialog::setTimeout(const int secs)
{
    int hours = (secs/60/60);
    if(hours){
        ui->timeout_hours_spinBox->setValue(
                    (hours <= ui->timeout_hours_spinBox->maximum()) ? hours : ui->timeout_hours_spinBox->maximum());
    }
    int minutes = (secs/60)%60;
    if(minutes){
        ui->timeout_minutes_spinBox->setValue(
                    (minutes <= ui->timeout_minutes_spinBox->maximum()) ? minutes : ui->timeout_minutes_spinBox->maximum());
    }
}

void ReminderDialog::setDays(const bool days[7])
{
    ui->monday_checkBox->setChecked(days[0]);
    ui->tuesday_checkBox->setChecked(days[1]);
    ui->wednesday_checkBox->setChecked(days[2]);
    ui->thursday_checkBox->setChecked(days[3]);
    ui->friday_checkBox->setChecked(days[4]);
    ui->saturday_checkBox->setChecked(days[5]);
    ui->sunday_checkBox->setChecked(days[6]);
}

void ReminderDialog::getDays(bool* days)
{
    days[0] = ui->monday_checkBox->isChecked();
    days[1] = ui->tuesday_checkBox->isChecked();
    days[2] = ui->wednesday_checkBox->isChecked();
    days[3] = ui->thursday_checkBox->isChecked();
    days[4] = ui->friday_checkBox->isChecked();
    days[5] = ui->saturday_checkBox->isChecked();
    days[6] = ui->sunday_checkBox->isChecked();
}

void ReminderDialog::toggleIntervalOptions(int idx)
{
    if(!idx) idx = ui->interval_comboBox->currentIndex();
    switch(idx){
    case 0: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->hide();
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->show();
        break;
    }
    case 1: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->hide();
        ui->days_groupBox->hide();
        ui->hours_groupBox->show();
        ui->minutely_groupBox->hide();
        break;
    }
    case 2: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->hide();
        ui->days_groupBox->show();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    case 3: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->show();
        ui->my_label->setText(tr("Every month (%1th of month)")
            .arg(ui->from_dateTimeEdit->date().day()));
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    case 4: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->show();
        ui->my_label->setText(tr("Every %1 of the mounth").arg(this->dayOfMonth(ui->from_dateTimeEdit->dateTime())));
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    case 5: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->show();
        ui->my_label->setText(tr("Every year (%1th of %2)")
            .arg(ui->from_dateTimeEdit->date().day())
            .arg(QDate::longMonthName(ui->from_dateTimeEdit->date().month())));
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    case 6: {
        ui->from_dateTimeEdit->setEnabled(true);
        ui->timeout_groupBox->hide();
        ui->my_groupBox->show();
        ui->my_label->setText(tr("Every year,\nevery %1 of %2")
            .arg(this->dayOfMonth(ui->from_dateTimeEdit->dateTime()))
            .arg(QDate::longMonthName(ui->from_dateTimeEdit->date().month())));
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    case 7: {
        ui->from_dateTimeEdit->setEnabled(false);
        ui->timeout_groupBox->show();
        ui->my_groupBox->hide();
        ui->days_groupBox->hide();
        ui->hours_groupBox->hide();
        ui->minutely_groupBox->hide();
        break;
    }
    default: break;
    }
}

void ReminderDialog::setFromDate(const QDateTime &datetime)
{
    ui->from_dateTimeEdit->setDateTime(datetime);
}

void ReminderDialog::setReminderName(const QString &name)
{
    ui->name_lineEdit->setText(name);
}

QString ReminderDialog::getReminderName() const
{
    return ui->name_lineEdit->text();
}

QDateTime ReminderDialog::getFromDate() const
{
    return ui->from_dateTimeEdit->dateTime();
}

void ReminderDialog::mediaState(Phonon::State newstate, Phonon::State oldstate)
{
    switch(newstate){
    case Phonon::PlayingState: {
        ui->audio_toolButton->disconnect(this);
        connect(ui->audio_toolButton, SIGNAL(clicked()), this, SLOT(stopPlaySound()));
        ui->audio_toolButton->setIcon(QIcon(":/Icons/icons/Stop.png"));
        break;
    }
    default: {
        ui->audio_toolButton->disconnect(this);
        connect(ui->audio_toolButton, SIGNAL(clicked()), this, SLOT(startPlaySound()));
        ui->audio_toolButton->setIcon(QIcon(":/Icons/icons/Play.png"));
        break;
    }
    }
}

QString ReminderDialog::dayOfMonth(const QDateTime datetime)
{
    QString str;
    int day = datetime.date().day();
    if(day <= 7) str.append(tr("first"));
    else if(day <= 14) str.append(tr("second"));
    else if(day <= 21) str.append(tr("third"));
    else if(day <= 28) {
        QDateTime next(datetime.addDays(7));
        if(next.date().month() == datetime.date().month()){
            str.append(tr("forth"));
        }
        else str.append(tr("last"));
    }
    else str.append(tr("last"));
    str.append(" ("+tr("day")+" "+QDate::longDayName(datetime.date().dayOfWeek())+")");
    return str;
}

bool ReminderDialog::isCorrectReminder()
{
    /*
      1 - check whether there is another reminder with the same name
      2 -
      */
    if(this->hasUrl()){
        QUrl url(this->getUrl(), QUrl::StrictMode);
        if(!url.isValid()){
            QMessageBox msgBox;
            msgBox.setIcon(QMessageBox::Warning);
            msgBox.setText(tr("Invalid URL: %1").arg(url.toString()));
            msgBox.exec();
            ui->url_lineEdit->setFocus();
            return false;
        }
    }
    return true;
}

void ReminderDialog::setDialog(bool dialog)
{
    ui->dialog_checkBox->setChecked(dialog);
}

bool ReminderDialog::getDialog() const
{
    return ui->dialog_checkBox->isChecked();
}

void ReminderDialog::setDialogText(const QString &text)
{
    ui->dialog_lineEdit->setText(text);
}

QString ReminderDialog::getDialogText() const
{
    return ui->dialog_lineEdit->text();
}

void ReminderDialog::setAutocloseInterval(const int secs)
{
    if(secs)
        ui->autoclose_spinBox->setValue(secs);
}

int ReminderDialog::getAutocloseInterval() const{
    return ui->autoclose_spinBox->value();
}

void ReminderDialog::setAudio(bool audio)
{
    ui->audio_checkBox->setChecked(audio);
}

bool ReminderDialog::getAudio() const
{
    return ui->audio_checkBox->isChecked();
}

void ReminderDialog::setAudioName(const QString &name)
{
    if(ui->audio_comboBox->findText(name) > -1)
        ui->audio_comboBox->setCurrentIndex(ui->audio_comboBox->findText(name));
}

QString ReminderDialog::getAudioName() const
{
    return ui->audio_comboBox->currentText();
}

void ReminderDialog::setTip(bool tip)
{
    ui->tooltip_checkBox->setChecked(tip);
}

bool ReminderDialog::getTip() const
{
    return ui->tooltip_checkBox->isChecked();
}

void ReminderDialog::setTipText(const QString &text)
{
    ui->tooltip_lineEdit->setText(text);
}

QString ReminderDialog::getTipText() const
{
    return ui->tooltip_lineEdit->text();
}

void ReminderDialog::toggleDialogOptons(bool toggle)
{
    ui->autoclose_checkBox->setEnabled(toggle);
    ui->autoclose_spinBox->setEnabled(toggle&&ui->autoclose_checkBox->isChecked());
}

void ReminderDialog::setIntervalIdx(const int idx)
{
    ui->interval_comboBox->setCurrentIndex(idx);
    this->setRepeat(true);
}

void ReminderDialog::setIntervalText(const QDateTime /*dt*/)
{
    switch(ui->interval_comboBox->currentIndex()){
    case 3: {
        ui->my_label->setText(tr("Every month (%1th of month)")
            .arg(ui->from_dateTimeEdit->date().day()));
        break;
    }
    case 4: {
        ui->my_label->setText(tr("Every %1 of the mounth").arg(this->dayOfMonth(ui->from_dateTimeEdit->dateTime())));
        break;
    }
    case 5: {
        ui->my_label->setText(tr("Every year (%1th of %2)")
            .arg(ui->from_dateTimeEdit->date().day())
            .arg(QDate::longMonthName(ui->from_dateTimeEdit->date().month())));
        break;
    }
    case 6: {
        ui->my_label->setText(tr("Every year,\nevery %1 of %2")
            .arg(this->dayOfMonth(ui->from_dateTimeEdit->dateTime()))
            .arg(QDate::longMonthName(ui->from_dateTimeEdit->date().month())));
        break;
    }
    default: break;
    }
}

void ReminderDialog::setLoadUrl(const bool load)
{
    ui->url_checkBox->setChecked(load);
}

void ReminderDialog::setUrl(const QString &url)
{
    ui->url_lineEdit->setText(url);
}

bool ReminderDialog::hasUrl() const
{
    return ui->url_checkBox->isChecked();
}

QString ReminderDialog::getUrl() const
{
    return ui->url_lineEdit->text();
}

bool ReminderDialog::getAutodelete() const
{
    return ui->autodelete_checkBox->isChecked();
}

void ReminderDialog::setAutodelete(const bool autodelete)
{
    ui->autodelete_checkBox->setChecked(autodelete);
}

void ReminderDialog::toggleShutdownOptions(bool toggle)
{
    ui->system_comboBox->setEnabled(toggle);
    ui->system_spinBox->setEnabled(toggle&&ui->system_comboBox->currentIndex());
}

void ReminderDialog::setShutdown(const bool shutdown)
{
    ui->system_checkBox->setChecked(shutdown);
}

bool ReminderDialog::getShutdown() const
{
    return ui->system_checkBox->isChecked();
}

int ReminderDialog::getShutdownTimeout() const
{
    return ui->system_spinBox->value();
}

void ReminderDialog::setShutdownTimeout(const int secs)
{
    ui->system_spinBox->setValue(secs);
}

void ReminderDialog::setShutdownType(const int type)
{
    ui->system_comboBox->setCurrentIndex(type);
}

int ReminderDialog::getShutdownType() const
{
    return ui->system_comboBox->currentIndex();
}

void ReminderDialog::enableShutdownTimeout(const int idx)
{
    ui->system_spinBox->setEnabled(idx>0&&idx!=3);
}

void ReminderDialog::setExecute(const bool execute)
{
    ui->execute_groupBox->setChecked(execute);
}

bool ReminderDialog::getExecute() const
{
    return ui->execute_groupBox->isChecked();
}

void ReminderDialog::setExecutePath(const QString &path)
{
    ui->execute_lineEdit->setText(path);
}

QString ReminderDialog::getExecutePath() const
{
    return ui->execute_lineEdit->text();
}

void ReminderDialog::setExecuteArgs(const QString &args)
{
    ui->execute_args_lineEdit->setText(args);
}

QString ReminderDialog::getExecuteArgs() const
{
    return ui->execute_args_lineEdit->text();
}

void ReminderDialog::chooseExecute()
{
    QString path = QFileDialog::getOpenFileName ( this, tr("Choose program or script") );
    if(!path.isEmpty()) ui->execute_lineEdit->setText(path);
}

void ReminderDialog::applySettings()
{
    ui->retranslateUi(this);
    ui->from_dateTimeEdit->setDisplayFormat(
                (qApp->property("use_secconds").toBool()) ?
                "dd.MM.yyyy HH:mm:ss" : "dd.MM.yyyy HH:mm"
                 );
}

void ReminderDialog::setCheckMissed(const bool check)
{
    ui->missed_checkBox->setChecked(check);
}

bool ReminderDialog::getCheckMissed() const
{
    return ui->missed_checkBox->isChecked();
}

void ReminderDialog::setEdit(bool edit)
{
    _edit = edit;
    this->setWindowTitle( edit ? tr("Edit reminder") : tr("New reminder"));
}
